/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.xuexiang.xui_lib.component.banner;

import ohos.agp.components.AttrHelper;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.PageSliderProvider;
import ohos.agp.components.Text;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.app.Context;

import com.xuexiang.xui_lib.ResourceTable;
import com.xuexiang.xui_lib.component.banner.interfaces.OnItemClickListener;
import com.xuexiang.xui_lib.component.banner.transform.PageTransformer;
import com.xuexiang.xui_lib.component.banner.widget.BannerItem;
import com.xuexiang.xui_lib.component.imageview.ImageLoader;
import com.xuexiang.xui_lib.util.Log;

import java.util.List;

import static ohos.agp.components.ComponentContainer.LayoutConfig.MATCH_PARENT;

/**
 * 封装Banner图ViewPager
 *
 * @since 2021-04-28
 */
public class BannerViewPager extends MyPageSlider {
    private static final String TAG = "BannerViewPager";
    private static final int constant = 2;
    private static final int textSize = 15;
    private static final int marginLeft = 25;
    private boolean isShow = true;
    private boolean isRadiusImage = false;
    private Class<? extends PageTransformer> transformer;
    private OnItemClickListener onItemClickListener;
    private List<String> urls;
    private List<String> titles;

    /**
     * 构造参数
     *
     * @param context 上下文
     */
    public BannerViewPager(Context context) {
        super(context);
    }

    /**
     * 构造参数
     *
     * @param context 上下文
     * @param attrSet AttrSet
     */
    public BannerViewPager(Context context, AttrSet attrSet) {
        super(context, attrSet);
    }

    /**
     * 构造参数
     *
     * @param context 上下文
     * @param attrSet AttrSet
     * @param styleName 类型名称
     */
    public BannerViewPager(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
    }

    /**
     * 是否显示轮播图片
     *
     * @param isBannerShow
     */
    public void setIndicatorShow(boolean isBannerShow) {
        this.isShow = isBannerShow;
    }

    /**
     * 是否显示圆角图片
     *
     * @param isRadiusImageShow 是否显示
     */
    public void setRadiusImage(boolean isRadiusImageShow) {
        this.isRadiusImage = isRadiusImageShow;
    }

    /**
     * 设置滑动动画
     *
     * @param transformer
     */
    public void setTransformer(Class<? extends PageTransformer> transformer) {
        this.transformer = transformer;
    }

    /**
     * 设置轮播图数据
     *
     * @param bannerItem
     */
    public void setData(BannerItem bannerItem) {
        try {
            urls = bannerItem.getImgUrl();
            titles = bannerItem.getTitle();
            BannerPagerAdapter adapter = new BannerPagerAdapter(isShow ? urls : titles);
            setProvider(adapter);
            int startSelectItem = getStartSelectItem(urls.size());
            setCurrentPage(startSelectItem);
            if (transformer != null) {
                setPageTransformer(transformer.newInstance());
            }
            if (isShow) {
                setBackground(new ShapeElement(getContext(), ResourceTable.Graphic_shape_image_viewpager_rectangle));
            } else {
                setBackground(new ShapeElement(getContext(), ResourceTable.Graphic_shape_text_viewpager_rectangle));
            }
        } catch (IllegalAccessException e) {
            Log.e(TAG, "BannerViewPager IllegalAccessException : " + e.getLocalizedMessage());
        } catch (InstantiationException e) {
            Log.e(TAG, "BannerViewPager InstantiationException : " + e.getLocalizedMessage());
        }
    }

    /**
     * 我们设置当前选中的位置为BannerPagerAdapter.LOOP_COUNT / 2,这样开始就能往左滑动,
     * 但是要保证这个值与getRealPosition 的 余数为0，因为要从第一页开始显示
     *
     * @param readCount
     * @return 开始位置
     */
    private int getStartSelectItem(int readCount) {
        if (readCount == 0) {
            return 0;
        }
        int count = BannerPagerAdapter.LOOP_COUNT / constant;
        int currentItem = count;
        if (count % readCount == 0) {
            return currentItem;
        }
        while (currentItem % readCount != 0) { // 直到找到从0开始的位置
            currentItem++;
        }
        return currentItem;
    }

    /**
     * 设置轮播点击事件
     *
     * @param onItemClickListener
     */
    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    /**
     * ViewPager适配器
     *
     * @param <T>
     * @since 2021-05-06
     */
    private class BannerPagerAdapter<T> extends PageSliderProvider {
        public static final int LOOP_COUNT = 5000;
        private List<T> imageViews;

        /**
         * 构造参数
         *
         * @param imageViews 图片地址
         * @noinspection checkstyle:Indentation
         */
        BannerPagerAdapter(List<T> imageViews) {
            this.imageViews = imageViews;
        }

        @Override
        public int getCount() {
            return imageViews.size() + LOOP_COUNT;
        }

        @Override
        public Object createPageInContainer(ComponentContainer container, int position) {
            Component component = mViewCache.get(position);
            if (component == null) {
                int realCount = position % imageViews.size();
                if (isShow) {
                    String imageUrl = (String) imageViews.get(realCount);
                    component = ImageLoader.get().loadImage(getContext(), imageUrl, isRadiusImage);
                } else {
                    component = showTitle((String) imageViews.get(realCount));
                }
                if (onItemClickListener != null) {
                    component.setClickedListener(new ClickedListener() {
                        @Override
                        public void onClick(Component component) {
                            onItemClickListener.onItemClick(component, titles.get(realCount), realCount);
                        }
                    });
                }
                mViewCache.put(position, component);
            }
            container.addComponent(component);
            return component;
        }

        @Override
        public void destroyPageFromContainer(ComponentContainer componentContainer, int position, Object o) {
            componentContainer.removeComponent((Component) o);
        }

        @Override
        public boolean isPageMatchToObject(Component component, Object obj) {
            return component == obj;
        }

        private Text showTitle(String title) {
            Text text = new Text(getContext());
            ComponentContainer.LayoutConfig layoutConfig = text.getLayoutConfig();
            layoutConfig.width = MATCH_PARENT;
            layoutConfig.height = MATCH_PARENT;
            text.setLayoutConfig(layoutConfig);
            text.setTextSize(AttrHelper.fp2px(textSize, getContext()));
            text.setMarginLeft(AttrHelper.vp2px(marginLeft, getContext()));
            text.setTextColor(new Color(Color.getIntColor("#ffffff")));
            text.setText(title);
            return text;
        }
    }
}
